package com.yiji.fintech.musfinance.common.aspect;

import com.acooly.core.utils.enums.ResultStatus;
import com.yiji.fintech.musfinance.center.base.order.OrderFacade;
import com.yiji.fintech.musfinance.center.base.result.ResultFacade;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.*;
import org.springframework.stereotype.Component;

/**
 * 前置异常处理切面
 * Created by ouwen@yiji.com} on 2017/9/16.
 */
@Slf4j
@Aspect
@Component
public class LogAspect {
    private ThreadLocal<ResultFacade> threadLocal = new ThreadLocal<>();
    /**
     * 切点
     */
    @Pointcut("@annotation(com.yiji.fintech.musfinance.common.annotation.LogAspectAnnotation)")
    public void exceptionAspect(){
    }
    /**
     * 前置通知
     * @param joinPoint
     */
    @Before("exceptionAspect()")
    public void before(JoinPoint joinPoint) {
        String className = joinPoint.getTarget().getClass().getName();
        String methodName = joinPoint.getSignature().getName();
        Object[] args = joinPoint.getArgs();
        //初始化结果
        ResultFacade result = (ResultFacade)args[1];
        OrderFacade order = (OrderFacade)args[0];
        //保存本地线程变量
        threadLocal.set(result);
        log.info("GID【{}}】外部流水号【{}】内部流水号【{}】Order:【{}】"+ "执行方法【{}】入参【{}】",order.getGid(),order.getMerchOrderNo(),order.getBizOrderNo(),className,methodName,order);
    }
    @AfterReturning(value = "exceptionAspect()", returning = "returnVal")
    public void afterReturin(ResultFacade returnVal) {
        log.info("返回业务方结果【{}】",returnVal);
    }
    @AfterThrowing(value = "exceptionAspect()", throwing = "e")
    public void afterThrowing(Throwable e) {
        if (e instanceof RuntimeException) {
            log.error("业务发生异常",e);
        } else {
            log.error("未知异常",e);
        }
    }
    @Around(value = "exceptionAspect()")
    public ResultFacade around(ProceedingJoinPoint proceedingJoinPoint) throws Throwable {
        ResultFacade result;
        try {
            proceedingJoinPoint.proceed();
            result = threadLocal.get();
        } catch (Exception e) {
            result = threadLocal.get();
            result.setStatus(ResultStatus.failure);
            result.setCode(ResultStatus.failure.getCode());
            if (e instanceof RuntimeException) {
                result.setDetail(e.getMessage());
            } else {
                result.setDetail("未知异常");
            }
            log.error("LogAspect拦截到异常",e);
            return result;
        }
        return result;
    }
}
